package cn.yx.framework.util;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.*;
import java.util.Enumeration;
import java.util.zip.*;

public class ZipUtil {
    private static final Logger logger = LoggerFactory.getLogger(ZipUtil.class);
    static final int BUFFER = 8192;


    public ZipUtil() {
    }


    public static String gzip(String primStr) {
        if (primStr != null && primStr.length() != 0) {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            GZIPOutputStream gzip = null;

            try {
                gzip = new GZIPOutputStream(out);
                gzip.write(primStr.getBytes());
            } catch (IOException var12) {
                var12.printStackTrace();
                logger.error("gzip write output stream exception", var12);
            } finally {
                if (gzip != null) {
                    try {
                        gzip.close();
                    } catch (IOException var11) {
                        var11.printStackTrace();
                    }
                }

            }

            return (new BASE64Encoder()).encode(out.toByteArray());
        } else {
            return primStr;
        }
    }

    public static String gunzip(String compressedStr) {
        if (compressedStr == null) {
            return null;
        } else {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ByteArrayInputStream in = null;
            GZIPInputStream ginzip = null;
            Object compressed = null;
            String decompressed = null;

            try {
                byte[] compressed1 = (new BASE64Decoder()).decodeBuffer(compressedStr);
                in = new ByteArrayInputStream(compressed1);
                ginzip = new GZIPInputStream(in);
                byte[] e = new byte[1024];
                boolean offset = true;

                int offset1;
                while ((offset1 = ginzip.read(e)) != -1) {
                    out.write(e, 0, offset1);
                }

                decompressed = out.toString();
            } catch (IOException var24) {
                var24.printStackTrace();
            } finally {
                if (ginzip != null) {
                    try {
                        ginzip.close();
                    } catch (IOException var23) {
                        logger.error("close gzip input stream exception", var23);
                    }
                }

                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException var22) {
                        logger.error("", var22);
                    }
                }

                try {
                    out.close();
                } catch (IOException var21) {
                    logger.error("", var21);
                }

            }

            return decompressed;
        }
    }

    public static final String zip(String str) {
        if (str == null) {
            return null;
        } else {
            ByteArrayOutputStream out = null;
            ZipOutputStream zout = null;
            String compressedStr = null;

            try {
                out = new ByteArrayOutputStream();
                zout = new ZipOutputStream(out);
                zout.putNextEntry(new ZipEntry("0"));
                zout.write(str.getBytes());
                zout.closeEntry();
                byte[] compressed1 = out.toByteArray();
                compressedStr = (new BASE64Encoder()).encodeBuffer(compressed1);
            } catch (IOException var18) {
                Object compressed = null;
            } finally {
                if (zout != null) {
                    try {
                        zout.close();
                    } catch (IOException var17) {
                        logger.error("", var17);
                    }
                }

                if (out != null) {
                    try {
                        out.close();
                    } catch (IOException var16) {
                        logger.error("", var16);
                    }
                }

            }

            return compressedStr;
        }
    }

    public static final String unzip(String compressedStr) {
        if (compressedStr == null) {
            return null;
        } else {
            ByteArrayOutputStream out = null;
            ByteArrayInputStream in = null;
            ZipInputStream zin = null;
            String decompressed = null;

            try {
                byte[] e = (new BASE64Decoder()).decodeBuffer(compressedStr);
                out = new ByteArrayOutputStream();
                in = new ByteArrayInputStream(e);
                zin = new ZipInputStream(in);
                zin.getNextEntry();
                byte[] buffer = new byte[1024];

                int offset;
                while ((offset = zin.read(buffer)) != -1) {
                    out.write(buffer, 0, offset);
                }

                decompressed = out.toString();
            } catch (IOException var24) {
                decompressed = null;
            } finally {
                if (zin != null) {
                    try {
                        zin.close();
                    } catch (IOException var23) {
                        logger.error("", var23);
                    }
                }

                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException var22) {
                        logger.error("", var22);
                    }
                }

                if (out != null) {
                    try {
                        out.close();
                    } catch (IOException var21) {
                        logger.error("", var21);
                    }
                }

            }

            return decompressed;
        }
    }

    public static void writeZip(String[] strs, String zipname, String temppath) throws IOException {

        File dir = new File(temppath);
        if (!dir.exists()) {
            dir.mkdirs();//可创建多级目录，而mkdir()只能创建一级目录
        }

        String[] files = strs;
        OutputStream os = new BufferedOutputStream(new FileOutputStream(temppath + "//" + zipname));
        ZipOutputStream zos = new ZipOutputStream(os);
        byte[] buf = new byte[8192];
        int len;
        for (int i = 0; i < files.length; i++) {
            File file = new File(files[i]);
            if (!file.isFile()) continue;
            ZipEntry ze = new ZipEntry(file.getName());
            zos.putNextEntry(ze);
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
            while ((len = bis.read(buf)) > 0) {
                zos.write(buf, 0, len);
            }
            //zos.closeEntry();
            bis.close();
        }
        zos.setEncoding("GBK");
        for (int i = 0; i < files.length; i++) {
            File file = new File(files[i]);
            file.delete();
        }
        zos.closeEntry();
        zos.close();
        os.close();
    }

    public static void decompress(String srcPath, String dest) throws Exception {

        File file = new File(srcPath);

        if (!file.exists()) {
            throw new RuntimeException(srcPath + "所指文件不存在");
        }

        ZipFile zf = new ZipFile(file);
        Enumeration entries = zf.getEntries();
        ZipEntry entry = null;
        while (entries.hasMoreElements()) {
            entry = (ZipEntry) entries.nextElement();
            System.out.println("解压" + entry.getName());
            if (entry.isDirectory()) {
                String dirPath = dest + File.separator + entry.getName();
                File dir = new File(dirPath);
                dir.mkdirs();
            } else {
                // 表示文件
                File f = new File(dest + File.separator + entry.getName());
                if (!f.exists()) {
                    String dirs = f.getParent();//FileUtils.getParentPath(f);
                    File parentDir = new File(dirs);
                    parentDir.mkdirs();
                }

                f.createNewFile();

                // 将压缩文件内容写入到这个文件中

                InputStream is = zf.getInputStream(entry);

                FileOutputStream fos = new FileOutputStream(f);


                int count;

                byte[] buf = new byte[8192];

                while ((count = is.read(buf)) != -1) {

                    fos.write(buf, 0, count);

                }

                is.close();

                fos.close();

            }

        }

    }

}
